﻿using System;

using System.Collections;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;

namespace ConfExpert.Utility.Peripheral
{
    public class Barcode
    {
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Checkdata", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_CheckdataN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Deletedata", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_DeletedataN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Openfile", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_OpenfileN(String lpFileName);
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Barcode", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_BarcodeN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Dataform", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_DataformN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Variable", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_VariableN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Constant", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_ConstantN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Procdure", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_ProcdureN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Table", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_TableN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Finish", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_FinishN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Download_Freetask", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Download_FreetaskN(String lpFileName);
        [DllImport("Remot.dll", EntryPoint = "PDX_Get_Last_Error", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Get_Last_ErrorN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Remot_Online", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Remot_OnlineN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Remot_Offline", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Remot_OfflineN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Remot_Set_Comm", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Remot_Set_CommN(String lpCommName, int BaudRate, byte DataBit, byte StopBit, byte Parity);
        [DllImport("Remot.dll", EntryPoint = "PDX_Ram_Test", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Ram_TestN();
        //[DllImport("Remot.dll", EntryPoint = "PDX_Get_Data", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        //static extern int PDX_Get_DataN(String lpcommand, [MarshalAs(UnmanagedType.VBByRefStr)] ref string lpbuffer);

        [DllImport("Remot.dll", EntryPoint = "PDX_Get_Data", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Get_DataN(String lpcommand, StringBuilder lpbuffer);
        [DllImport("Remot.dll", EntryPoint = "PDX_Get_Field", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Get_FieldN(StringBuilder lpbuffer);

        [DllImport("Remot.dll", EntryPoint = "PDX_Put_Data", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Put_DataN(String lpcommand, String lpbuffer);
        [DllImport("Remot.dll", EntryPoint = "PDX_Upload_Finish", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Upload_FinishN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Upload_Pause", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Upload_PauseN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Upload_Continue", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Upload_ContinueN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Upload", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_UploadN(String lpFormSelect);
        [DllImport("Remot.dll", EntryPoint = "PDX_Upload_Deletedata", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Upload_DeletedataN(String lpFormSelect);
        [DllImport("Remot.dll", EntryPoint = "PDX_Upload_Terminate", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Upload_TerminateN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Remot_Set_Debug_On", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Remot_Set_Debug_OnN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Remot_Set_Debug_Off", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Remot_Set_Debug_OffN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Wait_Time", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Wait_TimeN(int WaitTime);
        [DllImport("Remot.dll", EntryPoint = "PDX_Remot_Open_Comm", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern void PDX_Remot_Open_CommN();
        [DllImport("Remot.dll", EntryPoint = "PDX_Remot_Close_Comm", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern void PDX_Remot_Close_CommN();

        [DllImport("Remot.dll", EntryPoint = "PDX_Upload_File", ExactSpelling = true, CharSet = CharSet.Ansi, SetLastError = true)]
        static extern int PDX_Upload_FileN(String lpFormSelect, String lpFileName);

        static int[] sizes = new int[44];
        static Hashtable info = new Hashtable();
        struct PDX_info
        {
            static public string Name0 = null;
            static public string RecordSize0 = null;
            static public string NumberOfFields0 = null;
            static public string Name1 = null;
            static public string RecordSize1 = null;
            static public string NumberOfFields1 = null;
            static public string Name2 = null;
            static public string RecordSize2 = null;
            static public string NumberOfFields2 = null;
            static public string Name3 = null;
            static public string RecordSize3 = null;
            static public string NumberOfFields3 = null;
            static public string Name4 = null;
            static public string RecordSize4 = null;
            static public string NumberOfFields4 = null;
            static public string Name5 = null;
            static public string RecordSize5 = null;
            static public string NumberOfFields5 = null;
            static public string Name6 = null;
            static public string RecordSize6 = null;
            static public string NumberOfFields6 = null;
            static public string Name7 = null;
            static public string RecordSize7 = null;
            static public string NumberOfFields7 = null;
            static public string Name8 = null;
            static public string RecordSize8 = null;
            static public string NumberOfFields8 = null;
            static public string Reserved65 = null;
            static public string DeviceName = null;
            static public string Device = null;
            static public string UnitID = null;
            static public string Password = null;
            static public string RamSize = null;
            static public string SizeofFreeRam = null;
            static public string MainBattery = null;
            static public string BackBattery = null;
            static public string RS232_IR = null;
            static public string INT_AUX = null;
            static public string AuxDevice = null;
            static public string BackLightLCD = null;
            static public string BuzzerVolume = null;
            static public string AutoPowerOff = null;
            static public string PowerUpScan = null;
            static public string DateModeSetting = null;
        }

        static Barcode()
        {
            string[] strSizes = "8.5.2.8.5.2.8.5.2.8.5.2.8.5.2.8.5.2.8.5.2.8.5.2.8.5.2.65.8.8.8.4.4.4.1.1.1.1.1.1.1.1.1.1".Split(".".ToCharArray());
            for (int i = 0; i < strSizes.Length; i++)
                sizes[i] = int.Parse(strSizes[i]);
        }

        //remot.dll i Windows\system32 ye kopyala!
        //remot.dll in versiyonlarına (içindeki metod isimlerine) dump utility ile bak!

        static string ExtractChecksumDigit(string barcode)
        {
            if (barcode.Length < 13)
                return barcode;
            else
            {
                string sTemp = barcode.Substring(0, barcode.Length - 1);
                bool UPCA = sTemp.StartsWith("0"); //UPC-A da fazladan bir sıfır var..

                if (UPCA)
                    sTemp = sTemp.Substring(1);

                int iSum = 0;
                int iDigit = 0;

                // Calculate the checksum digit here.
                try
                {
                    for (int i = 1; i <= sTemp.Length; i++)
                    {
                        iDigit = Convert.ToInt32(sTemp.Substring(i - 1, 1));
                        if (UPCA)
                        {
                            if (i % 2 == 0)
                                iSum += iDigit * 1;
                            else
                                iSum += iDigit * 3;
                        }
                        else
                        {
                            if (i % 2 == 0)
                                iSum += iDigit * 3;
                            else
                                iSum += iDigit * 1;
                        }
                    }

                }
                catch (Exception)
                {
                    return string.Empty;
                }
                int iCheckSum = (10 - (iSum % 10)) % 10;
                if (iCheckSum.ToString() == barcode.Substring(barcode.Length - 1, 1))
                    return sTemp;
                else
                    return string.Empty;
                    //return sTemp + " *" + barcode.Substring(barcode.Length - 1, 1) + "* " + iCheckSum.ToString(); // String.Empty;
            }
        }
        //http://www.barcodeisland.com/ean8.phtml

        public static string ReadDevice()
        {
            String header, line = String.Empty;
            StringBuilder rdBuffer = new StringBuilder(255);
            try
            {
                //TODO: ZEBEX YAPILMASI GEREKENLER:
                //number of stop bits: burada 0. cihazda 1 olmalı
                //silabs i yükle ve DeviceManager->Ports tan konfigüre et. HW control. 8. Port
                //cihaz üzerindeki comm. ayarları buradakiyle aynı olmalı!
                //cihazın pilini şarj et
                //CP210x USB to UART Bridge VCP Drivers at http://www.silabs.com/products/mcu/pages/usbtouartbridgevcpdrivers.aspx
                //REMOTE.DLL programın çalıştığı yere veya Windows\systems32 klasörüne kopyala
                //çalışması için usb kablo üzerindeki besleme bağlı olmalı
                //barkod okumak için M2-M2, ana menü M1-M1
                if (PDX_Remot_Set_CommN("COM8", 38400, 8, 0, 0) == 0)
                    throw new ApplicationException();
                    //MessageBox.Show(PDX_Get_Last_ErrorN().ToString());

                PDX_Remot_Open_CommN();
                PDX_Remot_OnlineN();
                /*
                int result = PDX_Get_DataN("RX", rdBuffer);
                string t = rdBuffer.ToString();
                                
                int cnt = 0, cntx = 0;
                info = new Hashtable();
                PDX_info pDX_info = new PDX_info();
                System.Reflection.FieldInfo[] fields = pDX_info.GetType().GetFields();
                foreach (System.Reflection.FieldInfo field in fields)
                {
                    info.Add(field.Name, t.Substring(cntx, sizes[cnt]));
                    cntx += sizes[cnt];
                    cnt++;
                }
                int recordSize = int.Parse(info["RecordSize0"].ToString());
                */
                PDX_UploadN("0");           // upload form 0.
                PDX_Get_FieldN(rdBuffer);   // read form header.
                header = rdBuffer.ToString();

                while (PDX_Get_FieldN(rdBuffer) > 0)   // read line
                {
                    line += ExtractChecksumDigit(rdBuffer.ToString()) + Environment.NewLine;
                    //PDX_Upload_PauseN();        // pause upload procedure.
                    //PDX_Upload_ContinueN();     // continue upload procedure.
                }

                PDX_Upload_FinishN();    // terminate upload procedure.
                PDX_Upload_DeletedataN("0");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
            finally
            {
                PDX_Remot_OfflineN();
                PDX_Remot_Close_CommN();
            }
            return line;
        }

    }
}